package com.pigdogbay.cleverdicpro;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import android.os.AsyncTask;

public class ApplicationPresenter {
	
	IApplicationView _View;
	IApplicationModel _Model;
	AnagramPresenter _AnagramPresenter;
	private boolean _DictionaryLoadThreadLock = false;
	
	public void setView(IApplicationView view)
	{
		_View = view;
	}
	public void setModel(IApplicationModel model)
	{
		_Model = model;
	}
	public void setAnagramPresenter(AnagramPresenter presenter)
	{
		_AnagramPresenter = presenter;
	}
	
	public ApplicationPresenter(){}
	public ApplicationPresenter(IApplicationView view, IApplicationModel model){
		_View = view;
		_Model = model;
	}
	
	public void initialize()
	{
		setUpDictionary();
		try{checkFirstTime();}catch(Exception e){}
		try{_View.checkAppRate();}catch(Exception e){}
	}
	public void resume(){
		
	}
	public void pause(){
		_AnagramPresenter.stopSearch();
	}
	
	public void checkFirstTime()
	{
		if (_Model.isFirstTime())
		{
			_Model.setFirstTime(false);
			_View.showWelcomeScreen();
		}
	}
	
	public void setUpDictionary()
	{
		if (_Model.getDictionary()==null)
		{
			runDictionaryBackgroundWorker();
		}
		else
		{
			_AnagramPresenter.SetDictionary(_Model.getDictionary());
			_View.showReady();
		}
	}
	
	synchronized private void runDictionaryBackgroundWorker()
	{
		if (!_DictionaryLoadThreadLock) {
			new LoadDictionaryWorker().execute();
			ApplicationPresenter.this._DictionaryLoadThreadLock = true;
		}		
	}

	private List<String> loadDictionary() throws IOException
	{
		boolean loadPro = _Model.getUseLargeDictionary();
		List<String> standard = _Model.loadStandardDictionary();
		if (loadPro)
		{
			List<String> pro = _Model.loadProDictionary();
			standard.addAll(pro);
			Collections.sort(standard);
		}		
		return standard;
	}
	
	public void useLargeDictionarySettingChanged()
	{
		runDictionaryBackgroundWorker();
	}
	public void largeDictionaryPurchased()
	{
		_Model.setUseLargeDictionary(true);
		runDictionaryBackgroundWorker();
	}
	
	public void searchButtonPressed()
	{
		this._AnagramPresenter.Search();
	}
	
	public int getSearchButtonTextId()
	{
		return _Model.getUseLargeDictionary() ? R.string.button_search_pro : R.string.button_search;
	}
	
	/*
	 * Dictionary takes around 1000ms/2300ms to load on Nexus 7,
	 * 2600ms/8000ms on ACE phone. (Measured on 11 Sept 2013 with prior GC)
	 * Need to load this on a worker thread in the background to
	 * avoid the application freezing when starting up.
	 */
	private class LoadDictionaryWorker extends AsyncTask<Void, Void, Void> {
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			ApplicationPresenter.this._View.showLoadingDictionary();
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			ApplicationPresenter.this._DictionaryLoadThreadLock = false;
			ApplicationPresenter.this._View.showReady();
		}

		@Override
		protected Void doInBackground(Void... params) {
			//Memory intensive operation, causes HTC to crash if dictionary is reloaded
			//Running gc before adds 200-300 milliseconds on the load time (nexus 7)
			//but saves 1300 - 1500 milliseconds on the Ace
			_Model.setDictionary(null);
			_AnagramPresenter.SetDictionary(null);
			System.gc();
			try {
				List<String> dictionary = loadDictionary();
				_Model.setDictionary(dictionary);
				ApplicationPresenter.this._AnagramPresenter.SetDictionary(dictionary);
			}
			catch (Exception e) {
				ApplicationPresenter.this._View.showLoadingDictionaryError();
			}
			return null;
		}

	}
	
}
